package com.ruoyi.project.modules.interfaceGenerator.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.modules.domainInfo.domain.DomainObjectInfo;
import com.ruoyi.project.modules.domainInfo.service.IDomainInfoService;
import com.ruoyi.project.modules.errorCode.domain.ErrorCode;
import com.ruoyi.project.modules.errorCode.service.IErrorCodeService;
import com.ruoyi.project.modules.interfaceGenerator.domain.InterfaceGenerator;
import com.ruoyi.project.modules.interfaceGenerator.mapper.InterfaceGeneratorMapper;
import com.ruoyi.project.modules.interfaceGenerator.service.IInterfaceGeneratorService;
import com.ruoyi.project.modules.interfaceinfo.domain.InterfaceInfo;
import com.ruoyi.project.modules.interfaceinfo.domain.VirtualUsage;
import com.ruoyi.project.modules.interfaceinfo.service.IInterfaceInfoService;
import com.ruoyi.project.modules.interfaceinfo.service.IVirtualUsageService;
import com.ruoyi.project.modules.interfaceinfo.vo.InterfaceParam;
import com.ruoyi.project.modules.parameter.domain.InterfaceParamsFieldRelation;
import com.ruoyi.project.modules.parameter.domain.ParamsFieldRelation;
import com.ruoyi.project.modules.parameter.service.IInterfaceParamsFieldRelationService;
import com.ruoyi.project.modules.parameter.service.IParamsFieldRelationService;
import com.ruoyi.project.modules.processBranch.domain.ProcessBranch;
import com.ruoyi.project.modules.processBranch.service.IProcessBranchService;
import com.ruoyi.project.modules.processBranchCondition.domain.ProcessBranchCondition;
import com.ruoyi.project.modules.processBranchCondition.service.IProcessBranchConditionService;
import com.ruoyi.project.modules.processBranchConditionDetail.domain.ProcessBranchConditionDetail;
import com.ruoyi.project.modules.processBranchConditionDetail.service.IProcessBranchConditionDetailService;
import com.ruoyi.project.modules.processBranchEnd.domain.ProcessBranchEnd;
import com.ruoyi.project.modules.processBranchEnd.service.IProcessBranchEndService;
import com.ruoyi.project.modules.virtualUsageFieldMerge.domain.VirtualUsageFieldMerge;
import com.ruoyi.project.modules.virtualUsageFieldMerge.service.IVirtualUsageFieldMergeService;
import com.ruoyi.project.modules.virtualUsageGroup.domain.VirtualUsageGroup;
import com.ruoyi.project.modules.virtualUsageGroup.service.IVirtualUsageGroupService;
import com.ruoyi.project.modules.virtualUsageGroupDetail.service.IVirtualUsageGroupDetailService;
import com.ruoyi.project.modules.virtualUsageParamSource.domain.VirtualUsageParamSource;
import com.ruoyi.project.modules.virtualUsageParamSource.service.IVirtualUsageParamSourceService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 接口数据格式信息Service业务层处理
 *
 * @author smallrain
 * @date 2022-07-14
 */
@Service
public class InterfaceGeneratorServiceImpl implements IInterfaceGeneratorService {
    @Resource
    private InterfaceGeneratorMapper interfaceGeneratorMapper;

    /**
     * 查询接口数据格式信息
     *
     * @param interfaceId 接口数据格式信息主键
     * @return 接口数据格式信息
     */
    @Override
    public InterfaceGenerator selectInterfaceGeneratorByInterfaceId(Long interfaceId) {
        return interfaceGeneratorMapper.selectInterfaceGeneratorByInterfaceId(interfaceId);
    }

    /**
     * 查询接口数据格式信息列表
     *
     * @param interfaceGenerator 接口数据格式信息
     * @return 接口数据格式信息
     */
    @Override
    public List<InterfaceGenerator> selectInterfaceGeneratorList(InterfaceGenerator interfaceGenerator) {
        return interfaceGeneratorMapper.selectInterfaceGeneratorList(interfaceGenerator);
    }

    /**
     * 新增接口数据格式信息
     *
     * @param interfaceGenerator 接口数据格式信息
     * @return 结果
     */
    @Override
    public int insertInterfaceGenerator(InterfaceGenerator interfaceGenerator) {
        return interfaceGeneratorMapper.insertInterfaceGenerator(interfaceGenerator);
    }

    /**
     * 修改接口数据格式信息
     *
     * @param interfaceGenerator 接口数据格式信息
     * @return 结果
     */
    @Override
    public int updateInterfaceGenerator(InterfaceGenerator interfaceGenerator) {
        return interfaceGeneratorMapper.updateInterfaceGenerator(interfaceGenerator);
    }

    /**
     * 批量删除接口数据格式信息
     *
     * @param interfaceIds 需要删除的接口数据格式信息主键
     * @return 结果
     */
    @Override
    public int deleteInterfaceGeneratorByInterfaceIds(String interfaceIds) {
        return interfaceGeneratorMapper.deleteInterfaceGeneratorByInterfaceIds(Convert.toStrArray(interfaceIds));
    }

    /**
     * 删除接口数据格式信息信息
     *
     * @param interfaceId 接口数据格式信息主键
     * @return 结果
     */
    @Override
    public int deleteInterfaceGeneratorByInterfaceId(Long interfaceId) {
        return interfaceGeneratorMapper.deleteInterfaceGeneratorByInterfaceId(interfaceId);
    }

    public void cacheData() {
        List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(new InterfaceInfo());
        for (InterfaceInfo interfaceInfo : interfaceInfoList) {
            saveOrUpdate(interfaceInfo);
        }
    }

    public void saveOrUpdate(InterfaceInfo interfaceInfo) {
        InterfaceGenerator interfaceGenerator = new InterfaceGenerator();
        interfaceGenerator.setInterfaceId(interfaceInfo.getId());
        interfaceGenerator.setInterfaceName(interfaceInfo.getInterfaceName());
        interfaceGenerator.setFbType(interfaceInfo.getFbType());
        if ("1".equals(interfaceInfo.getFbType())) {
            Map<String, Object> data = new HashMap<>();
            data.put("basicInfo", convert(interfaceInfo));
            convertParam(interfaceInfo.getId(), "1", data);
            interfaceGenerator.setContent(JSONObject.toJSONString(data));
        } else if ("2".equals(interfaceInfo.getFbType())) {
            Map<String, Object> data = new HashMap<>();
            data.put("basicInfo", convert(interfaceInfo));
            convertParam(interfaceInfo.getId(), "2", data);
            if (interfaceInfo.getIsBranch().equals("N")) {
                data.put("virtualUseCase", queryVirtualUsage(interfaceInfo));
            } else {
                data.put("virtualUseCase", queryProcessBranch(interfaceInfo.getId()));
            }
            interfaceGenerator.setContent(JSONObject.toJSONString(data));
        } else {
            Map<String, Object> data = new HashMap<>();
            data.put("basicInfo", convert(interfaceInfo));
            convertParam(interfaceInfo.getId(), "4", data);
            if (interfaceInfo.getIsBranch().equals("N")) {
                data.put("virtualUseCase", queryVirtualUsage(interfaceInfo));
            } else {
                data.put("virtualUseCase", this.queryProcessBranch(interfaceInfo.getId()));
            }
            interfaceGenerator.setContent(JSONObject.toJSONString(data));
        }
        int i = this.interfaceGeneratorMapper.updateInterfaceGenerator(interfaceGenerator);
        if (i == 0) {
            this.interfaceGeneratorMapper.insertInterfaceGenerator(interfaceGenerator);
        }
    }


    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public void generator(List<Long> interfaceIds) {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setIds(interfaceIds);
        List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
        if (CollectionUtil.isNotEmpty(interfaceInfoList)) {
            for (InterfaceInfo info : interfaceInfoList) {
                this.threadPoolTaskExecutor.execute(()->{
                    try {
                        saveOrUpdate(info);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
                this.threadPoolTaskExecutor.execute(()->{
                    try {
                        cacheDataByInterfaceId(info);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    @Resource
    private IInterfaceInfoService interfaceInfoService;

    @Resource
    private IVirtualUsageService virtualUsageService;

    @Resource
    private IProcessBranchService processBranchService;

    @Resource
    private IVirtualUsageParamSourceService virtualUsageParamSourceService;

    @Resource
    private IVirtualUsageFieldMergeService virtualUsageFieldMergeService;

    public List<Map<String, Object>> query(String interfaceName, String fbType, String isEditTest , String isTimingTask, String lifeCycle) {
        if ("Y".equals(isTimingTask)) {
            InterfaceGenerator interfaceGenerator = new InterfaceGenerator();
            interfaceGenerator.setFbType(fbType);
            if (StringUtils.isNotEmpty(interfaceName)) {
                interfaceGenerator.setInterfaceName(interfaceName);
            }
            List<InterfaceGenerator> interfaceGenerators = this.interfaceGeneratorMapper.selectInterfaceGeneratorList(interfaceGenerator);
            List<Map<String, Object>> result = new ArrayList<>();
            for (InterfaceGenerator generator : interfaceGenerators) {
                result.add(JSONObject.parseObject(generator.getContent()));
            }
            return result;
        } else {
            InterfaceInfo interfaceInfo1 = new InterfaceInfo();
            interfaceInfo1.setFbType(fbType);
            if (StringUtils.isNotEmpty(interfaceName)) {
                interfaceInfo1.setInterfaceName(interfaceName);
            }
            if (StringUtils.isNotEmpty(isEditTest)) {
                interfaceInfo1.setIsEditTest(isEditTest);
            }
            if (StringUtils.isNotEmpty(lifeCycle)) {
                interfaceInfo1.setLifeCycle(lifeCycle);
            }
            List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(interfaceInfo1);
            List<Map<String, Object>> result = new ArrayList<>();
            for (InterfaceInfo interfaceInfo : interfaceInfoList) {
                Map<String, Object> data = new HashMap<>();
                if ("1".equals(interfaceInfo.getFbType())) {
                    data.put("basicInfo", convert(interfaceInfo));
                    convertParam(interfaceInfo.getId(), "1", data);
                } else if ("2".equals(interfaceInfo.getFbType())) {
                    data.put("basicInfo", convert(interfaceInfo));
                    convertParam(interfaceInfo.getId(), "2", data);
                    if (interfaceInfo.getIsBranch().equals("N")) {
                        data.put("virtualUseCase", queryVirtualUsage(interfaceInfo));
                    } else {
                        data.put("virtualUseCase", queryProcessBranch(interfaceInfo.getId()));
                    }
                } else {
                    data.put("basicInfo", convert(interfaceInfo));
                    convertParam(interfaceInfo.getId(), "4", data);
                    if (interfaceInfo.getIsBranch().equals("N")) {
                        data.put("virtualUseCase", queryVirtualUsage(interfaceInfo));
                    } else {
                        data.put("virtualUseCase", this.queryProcessBranch(interfaceInfo.getId()));
                    }
                }
                result.add(data);
            }
            return result;
        }
    }

    @Override
    public void cacheDataByInterfaceId(InterfaceInfo interfaceInfo) {
        if ("2".equals(interfaceInfo.getFbType()) || "3".equals(interfaceInfo.getFbType())) {
            handler(interfaceInfo.getId());
        }
    }

    private void handler(Long interfaceId) {
        VirtualUsage virtualUsage = new VirtualUsage();
        virtualUsage.setRelationInterfaceId(interfaceId);
        List<VirtualUsage> virtualUsageList = this.virtualUsageService.selectVirtualUsageList(virtualUsage);
        if (CollectionUtil.isNotEmpty(virtualUsageList)) {
            for (VirtualUsage usage : virtualUsageList) {
                InterfaceInfo interfaceInfo = this.interfaceInfoService.selectInterfaceInfoById(usage.getInterfaceId());
                if (interfaceInfo != null) {
                    this.saveOrUpdate(interfaceInfo);
                }
                if ("3".equals(interfaceInfo.getFbType())) {
                    handler(interfaceInfo.getId());
                }
            }
        }
    }

    @Resource
    private ISysDictTypeService sysDictTypeService;

    private SysDictData getDictRemark(String dictType, String value) {
        if (value == null) return null;
        List<SysDictData> sysDictData = sysDictTypeService.selectDictDataByType(dictType);
        if (CollectionUtil.isNotEmpty(sysDictData)) {
            for (SysDictData sysDictDatum : sysDictData) {
                if (sysDictDatum.getDictValue().equals(value)) {
                    return sysDictDatum;
                }
            }
        }
        return null;
    }

    private List<Map<String, Object>> queryVirtualUsage(InterfaceInfo info) {
        VirtualUsage virtualUsage = new VirtualUsage();
        virtualUsage.setRelationInterfaceId(info.getId());
        List<VirtualUsage> virtualUsages = virtualUsageService.selectVirtualUsages(virtualUsage);
        return this.convertVirtualUsageList(virtualUsages);
    }

    private List<Map<String, Object>> convertVirtualUsageList(List<VirtualUsage> virtualUsages) {
        List<Map<String, Object>> virtualUseCase = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(virtualUsages)) {
            for (VirtualUsage usage : virtualUsages) {
                Map<String, Object> data = new HashMap<>();
                data.put("virtualMethodId", usage.getInterfaceId());
                data.put("virtualMethodName", usage.getSlaveInterfaceName());
                data.put("virtualMethodEnName", usage.getDubboUrl());
                data.put("virtualMethodDesc", usage.getDescription());
                data.put("isMaster", usage.getIsMaster());
                data.put("appType", usage.getSlaveAppType());
                data.put("methodType", "1".equals(usage.getSlaveFbType()) ? "METHOD" : "2".equals(usage.getSlaveFbType()) ? "BFF" : "DUBBO");

                if (StringUtils.isNotEmpty(usage.getErrorCode())) {
                    data.put("errorCode", usage.getErrorCode());
                    ErrorCode errorCode = new ErrorCode();
                    errorCode.setErrorCode(usage.getErrorCode());
                    List<ErrorCode> errorCodes = this.errorCodeService.selectErrorCodeList(errorCode);
                    if (CollectionUtil.isNotEmpty(errorCodes)) {
                        data.put("errorDetail", errorCodes.get(0).getErrorCodeDetail());
                    }
                }
                data.put("sortNum", usage.getSortNum());
                Map<String, Object> model = new HashMap<>();
                model.put("virtualUsageModelContent", usage.getSelfModel());
                model.put("virtualUsageModelCode", usage.getModel());
                SysDictData virtualUsageModel = getDictRemark("virtualUsageModel", usage.getModel());
                if (virtualUsageModel != null) {
                    model.put("virtualUsageModelRemark", virtualUsageModel.getRemark());
                    model.put("isCreateMethod", virtualUsageModel.getIsCreateMethod());
                }
                model.put("outParamStrategy", usage.getIsAllowEmpty());
                data.put("virtualUsageModel", model);
                convertParam(usage.getId(), "3", data);
                virtualUseCase.add(data);
            }
        }
        return virtualUseCase;
    }

    private Map<String, Object> convertParam(Long interfaceId, String interfaceType, Map<String, Object> data) {
        List<Map<String, Object>> requestBody = new ArrayList<>();
        List<Map<String, Object>> response = new ArrayList<>();
        List<InterfaceParam> requestList = null;
        if ("3".equals(interfaceType)) {
            requestList = this.interfaceInfoService.virtualUsageInParamList(interfaceType, interfaceId, null, null);
        } else {
            requestList = this.interfaceInfoService.paramList(interfaceType, interfaceId, "1");
        }
        if (CollectionUtil.isNotEmpty(requestList)) {
            for (InterfaceParam interfaceParam : requestList) {
                requestBody.add(convertField(interfaceParam, "1", interfaceType));
            }
        }
        List<InterfaceParam> responseList = this.interfaceInfoService.paramList(interfaceType, interfaceId, "2");
        if (CollectionUtil.isNotEmpty(responseList)) {
            Map<String, List<VirtualUsageParamSource>> record = new HashMap<>();
            Map<Long, List<VirtualUsageFieldMerge>> mergeRecord = new HashMap<>();
            if ("2".equals(interfaceType) || "4".equals(interfaceType)) {
                // 出参来源
                VirtualUsageParamSource virtualUsageParamSource = new VirtualUsageParamSource();
                virtualUsageParamSource.setInterfaceId(interfaceId);
                virtualUsageParamSource.setIsInParam("2");
                List<VirtualUsageParamSource> virtualUsageParamSourceList = this.virtualUsageParamSourceService.selectVirtualUsageParamSourceList(virtualUsageParamSource);
                if (CollectionUtil.isNotEmpty(virtualUsageParamSourceList)) {
                    for (VirtualUsageParamSource paramSource : virtualUsageParamSourceList) {
                        List<VirtualUsageParamSource> virtualUsageParamSourceList1 = record.computeIfAbsent(paramSource.getObjectId() + paramSource.getType(), key -> new ArrayList<>());
                        virtualUsageParamSourceList1.add(paramSource);
                    }
                }
            } else if ("3".equals(interfaceType)) {
                // 字段融合
                VirtualUsageFieldMerge virtualUsageFieldMerge = new VirtualUsageFieldMerge();
                virtualUsageFieldMerge.setVirtualUsageId(interfaceId);
                List<VirtualUsageFieldMerge> virtualUsageFieldMerges = this.virtualUsageFieldMergeService.selectVirtualUsageFieldMergeList(virtualUsageFieldMerge);
                if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges)) {
                    mergeRecord = virtualUsageFieldMerges.stream().collect(Collectors.groupingBy(VirtualUsageFieldMerge::getObjectId));
                }
            }
            for (InterfaceParam interfaceParam : responseList) {
                if ("2".equals(interfaceType) || "4".equals(interfaceType)) {
                    interfaceParam.setVirtualUsageParamSources(record.get(interfaceParam.getId() + "1"));
                    if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                        for (InterfaceParam child : interfaceParam.getChildren()) {
                            child.setVirtualUsageParamSources(record.get(child.getId() + "2"));
                        }
                    }
                } else if ("3".equals(interfaceType)) {
                    if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                        for (InterfaceParam child : interfaceParam.getChildren()) {
                            List<VirtualUsageFieldMerge> virtualUsageFieldMerges = mergeRecord.get(child.getId());
                            if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges)) {
                                child.setMergeId(virtualUsageFieldMerges.get(0).getMergeObjectId());
                            }
                        }
                    }
                }
                response.add(convertField(interfaceParam, "2", interfaceType));
            }
        }
        data.put("requestBody", requestBody);
        data.put("response", response);
        return data;
    }

    @Autowired
    private IInterfaceParamsFieldRelationService interfaceParamsFieldRelationService;
    @Autowired
    private IParamsFieldRelationService paramsFieldRelationService;

    /**
     * 接口字段判断逻辑：
     * if（模式！=空 and 可以重置）
     *       返回 模式编码
     *
     * 虚拟用况字段判断逻辑：
     * if（ 字段模式！=空 and 可以重置） and  （虚拟用况的所属接口的字段 不可以重置）
     *      返回 模式编码
     * @param interfaceParam
     * @param interfaceType
     * @param type
     * @return
     */
    private Map<String, Object> paramDetail(InterfaceParam interfaceParam, String interfaceType, String type, String isInParam) {
        Map<String, Object> paramDetail = new HashMap<>();
        if ("1".equals(isInParam)) {
            boolean flag = false;
            if ("Y".equals(interfaceParam.getIsUpdate()) && StringUtils.isNotEmpty(interfaceParam.getDesignContent())) {
                if ("3".equals(interfaceType)) {
                    List<Long> ids = Arrays.asList(interfaceParam.getId());
                    List<InterfaceParamsFieldRelation> interfaceParamsFieldRelationList = this.interfaceParamsFieldRelationService.selectInterfaceParamsFieldRelationByDataRelationId(ids, "1");
                    if (CollectionUtil.isNotEmpty(interfaceParamsFieldRelationList)) {
                        if ("N".equals(interfaceParamsFieldRelationList.get(0).getIsUpdate())) {
                            flag = true;
                        }
                    } else {
                        flag = true;
                    }
                    List<ParamsFieldRelation> paramsFieldRelationList = this.paramsFieldRelationService.selectParamsFieldRelationListByDataRelationId(ids, "2");
                    if (CollectionUtil.isNotEmpty(paramsFieldRelationList)) {
                        if ("N".equals(paramsFieldRelationList.get(0).getIsUpdate())) {
                            flag = true;
                        }
                    } else {
                        flag = true;
                    }
                } else {
                    flag = true;
                }
            }
            if (flag) {
                if (StringUtils.isNotEmpty(interfaceParam.getDictValue())) {
                    paramDetail.put("designContent", interfaceParam.getDictValue());
                } else {
                    paramDetail.put("designContent", interfaceParam.getFieldDescription());
                }
                if (StringUtils.isNotEmpty(interfaceParam.getDesignContent()) && interfaceParam.getDesignContent().contains(",")) {
                    paramDetail.put("paramModeCode", interfaceParam.getDesignContent().split(","));
                } else {
                    paramDetail.put("paramModeCode", interfaceParam.getDesignContent());
                }
            }
            if (StringUtils.isNotEmpty(interfaceParam.getIsRequired())) {
                paramDetail.put("isRequired", "Y".equals(interfaceParam.getIsRequired()) ? "是" : "否");
            }
            paramDetail.put("isEnum", "Y".equals(interfaceParam.getIsFieldEnum()) ? "是" : "否");
            if ("Y".equals(interfaceParam.getIsFieldEnum())) {
                if (StringUtils.isNotEmpty(interfaceParam.getDictValue())) {
                    paramDetail.put("designContent", interfaceParam.getDictValue());
                } else if (StringUtils.isNotEmpty(interfaceParam.getFieldDescription())){
                    paramDetail.put("designContent", interfaceParam.getFieldDescription());
                }
            }
        } else {
            if (StringUtils.isNotEmpty(interfaceParam.getOrderType()) && !"0".equals(interfaceParam.getOrderType())) {
                paramDetail.put("orderType", interfaceParam.getOrderType());
            }
            if (StringUtils.isNotEmpty(interfaceParam.getIsAllowEmpty())) {
                paramDetail.put("outParamStrategy", interfaceParam.getIsAllowEmpty());
            }
            if (StringUtils.isNotEmpty(interfaceParam.getTreeModel())) {
                paramDetail.put("treeModel", interfaceParam.getTreeModel());
            }
            if (StringUtils.isNotEmpty(interfaceParam.getOtherModel())) {
                paramDetail.put("otherModel", interfaceParam.getOtherModel());
            }
        }
        return paramDetail;
    }

    private Map<String, Object> convertField(InterfaceParam interfaceParam, String isInParam, String interfaceType) {
        Map<String, Object> data = new HashMap<>();
        data.put("paramId", interfaceParam.getFieldId());
        data.put("condition", interfaceParam.getOperate());
        data.put("conditionWay", interfaceParam.getConditionWay());
        data.put("uniqueId", interfaceParam.getId() + "_1");
        if ("2".equals(isInParam)) {
            data.put("uniqueOutId", interfaceParam.getId() + "_1");
            data.put("isTree", interfaceParam.getIsTree());
            data.put("nodeType", interfaceParam.getNodeType());
        }
        if (interfaceParam.getDataRelationId() != null && interfaceParam.getDataRelationType() != null) {
            data.put("uniqueSourceId", interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType());
        }
        if (StringUtils.isNotEmpty(interfaceParam.getErrorCode())) {
            data.put("errorCode", interfaceParam.getErrorCode());
            ErrorCode errorCode = new ErrorCode();
            errorCode.setErrorCode(interfaceParam.getErrorCode());
            List<ErrorCode> errorCodes = this.errorCodeService.selectErrorCodeList(errorCode);
            if (CollectionUtil.isNotEmpty(errorCodes)) {
                data.put("errorDetail", errorCodes.get(0).getErrorCodeDetail());
            }
        }
        /**
         * BFF Dubbo接口出参uniqueSourceId  的值 加个前缀 out_
         * BFF Dubbo虚拟用况出参uniqueOutId   的值 加个前缀 out_
         *
         * 例如：uniqueSourceId  ： out_123456
         *      uniqueOutId   :  out_123456
         */
        if ("2".equals(isInParam)) {
            if ("2".equals(interfaceType) || "4".equals(interfaceType)) {
                List<VirtualUsageParamSource> virtualUsageParamSources = interfaceParam.getVirtualUsageParamSources();
                List<String> uniqueSourceIds = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(virtualUsageParamSources)) {
                    virtualUsageParamSources.forEach( e -> {
                        uniqueSourceIds.add("out_" + e.getSourceobjectId() + "_" + e.getSourceType());
                    });
                    data.put("uniqueSourceIds", uniqueSourceIds);
                    data.put("uniqueSourceId", uniqueSourceIds.get(0));
                } else {
                    data.put("uniqueSourceId", "out_" + interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType());
                }
                data.remove("uniqueOutId");
            } else {
                data.put("uniqueOutId", "out_" + interfaceParam.getId() + "_1");
            }
        }
        data.put("fieldName", interfaceParam.getFieldName());
        data.put("fieldEnName", interfaceParam.getFieldEnName());
        data.put("tableName", interfaceParam.getTableName());
        data.put("tableEnName", interfaceParam.getTableEnName());
        Map<String, Object> paramDetail = this.paramDetail(interfaceParam, interfaceType, "1", isInParam);

        if (interfaceParam.getObjectType().equals("2")) {
            data.put("isCollection", "是");
            data.put("paramId", interfaceParam.getFieldId());
            data.put("dtoName", StringUtils.isNotEmpty(interfaceParam.getObjectDtoName()) ? interfaceParam.getObjectDtoName().toString() : interfaceParam.getObjectDtoName());
            if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                List<Map<String, Object>> children = new ArrayList<>();
                for (InterfaceParam child : interfaceParam.getChildren()) {
                    Map<String, Object> childData = new HashMap<>();
                    childData.put("paramId", child.getFieldId());
                    childData.put("uniqueId", child.getId() + "_2");
                    childData.put("condition", child.getOperate());
                    childData.put("conditionWay", child.getConditionWay());

                    if (StringUtils.isNotEmpty(child.getErrorCode())) {
                        childData.put("errorCode", child.getErrorCode());
                        ErrorCode errorCode = new ErrorCode();
                        errorCode.setErrorCode(child.getErrorCode());
                        List<ErrorCode> errorCodes = this.errorCodeService.selectErrorCodeList(errorCode);
                        if (CollectionUtil.isNotEmpty(errorCodes)) {
                            childData.put("errorDetail", errorCodes.get(0).getErrorCodeDetail());
                        }
                    }
                    if ("2".equals(isInParam)) {
                        childData.put("uniqueOutId", child.getId() + "_2");
                        if ("3".equals(interfaceType)) {
                            childData.put("mergeId", "merge_" + child.getId());
                            if (child.getMergeId() != null) {
                                childData.put("mergeSourceId", "merge_" + child.getMergeId());
                            }
                        }
                    }
                    if (child.getDataRelationId() != null && child.getDataRelationType() != null) {
                        childData.put("uniqueSourceId", child.getDataRelationId() + "_" + child.getDataRelationType());
                    }

                    /**
                     * BFF Dubbo接口出参uniqueSourceId  的值 加个前缀 out_
                     * BFF Dubbo虚拟用况出参uniqueOutId   的值 加个前缀 out_
                     *
                     * 例如：uniqueSourceId  ： out_123456
                     *      uniqueOutId   :  out_123456
                     */
                    if ("2".equals(isInParam)) {
                        if ("2".equals(interfaceType) || "4".equals(interfaceType)) {
                            List<VirtualUsageParamSource> virtualUsageParamSources = child.getVirtualUsageParamSources();
                            List<String> uniqueSourceIds = new ArrayList<>();
                            if (CollectionUtil.isNotEmpty(virtualUsageParamSources)) {
                                virtualUsageParamSources.forEach( e -> {
                                    uniqueSourceIds.add("out_" + e.getSourceobjectId() + "_" + e.getSourceType());
                                });
                                childData.put("uniqueSourceIds", uniqueSourceIds);
                                childData.put("uniqueSourceId", uniqueSourceIds.get(0));
                            } else {
                                childData.put("uniqueSourceId", "out_" + child.getDataRelationId() + "_" + child.getDataRelationType());
                            }
                            childData.remove("uniqueOutId");
                        } else {
                            childData.put("uniqueOutId", "out_" + child.getId() + "_2");
                        }
                    }
                    childData.put("fieldName", child.getFieldName());
                    childData.put("fieldEnName", child.getFieldEnName());
                    childData.put("tableName", child.getTableName());
                    childData.put("tableEnName", child.getTableEnName());
                    Map<String, Object> childParamDetail = this.paramDetail(child, interfaceType, "2", isInParam);
                    childData.put("paramDetail", childParamDetail);
                    children.add(childData);
                }
                data.put("collectionFieldList", children);
            }
        } else {
            data.put("isCollection", "否");
        }
        data.put("paramDetail", paramDetail);
        return data;
    }

    @Resource
    private IDomainInfoService domainInfoService;

    @Resource
    private IVirtualUsageGroupService virtualUsageGroupService;

    private Map<String, Object> convert(InterfaceInfo interfaceInfo) {
        Map<String, Object> data = new HashMap<>();
        data.put("interfaceId", interfaceInfo.getId());
        data.put("interfaceName", interfaceInfo.getInterfaceName());
        data.put("interfaceUrl", interfaceInfo.getInterfaceUrl());
        data.put("appType", interfaceInfo.getAppType());
        if (interfaceInfo.getDomainObjectId() != null) {
            DomainObjectInfo domainObjectInfo = domainInfoService.selectDomainObjectById(interfaceInfo.getDomainObjectId());
            if (domainObjectInfo != null) {
                data.put("domain", domainObjectInfo.getDomainEnName());
                data.put("domainObject", domainObjectInfo.getObjectEnName());
            }
        }
        //data.put("domain", StringUtils.isNotEmpty(interfaceInfo.getDomain()) ? interfaceInfo.getDomain().trim() : interfaceInfo.getDomain());
        data.put("fbType", interfaceInfo.getFbType().equals("1") ? "METHOD" : interfaceInfo.getFbType().equals("2") ? "BFF" : "DUBBO");
        //1=增,2=删,3=改,4=查
        data.put("optType", interfaceInfo.getOptType().equals("1") ? "增" : interfaceInfo.getOptType().equals("2") ? "删" : interfaceInfo.getOptType().equals("3") ? "改" : interfaceInfo.getOptType().equals("4") ? "查":"时间切片");
        data.put("specialInterface", interfaceInfo.getSpecialInterface());
        data.put("isRisk", interfaceInfo.getIsRisk().equals("Y") ? "是" : "否");
        data.put("isTree", "Y".equals(interfaceInfo.getIsTree()) ? "是" : "否");
        data.put("requestDtoName", StringUtils.isNotEmpty(interfaceInfo.getInParamDtoName()) ? interfaceInfo.getInParamDtoName().trim() : interfaceInfo.getInParamDtoName());
        data.put("responseDtoName", StringUtils.isNotEmpty(interfaceInfo.getOutParamDtoName()) ? interfaceInfo.getOutParamDtoName().trim() : interfaceInfo.getOutParamDtoName());
        data.put("isPage", "Y".equals(interfaceInfo.getIsPage()) ? "是" : "否");
        data.put("interfaceDescription", interfaceInfo.getInterfaceDescription());
        data.put("nonFunctionalRequirements", interfaceInfo.getNonFunctionalRequirements());
        data.put("isBoundary", "Y".equals(interfaceInfo.getIsBoundary()) ? "是" : "否");
        data.put("isPlatform", "Y".equals(interfaceInfo.getIsPlatform()) ? "是" : "否");
        data.put("isCommon", "Y".equals(interfaceInfo.getIsCommon()) ? "是" : "否");
        data.put("isManage", "Y".equals(interfaceInfo.getIsManage()) ? "是" : "否");
        data.put("isBranch", "Y".equals(interfaceInfo.getIsBranch()) ? "是" : "否");
        data.put("isEnd", "9".equals(interfaceInfo.getLifeCycle()) ? "是" : "否");
        data.put("isEditTest", "Y".equals(interfaceInfo.getIsEditTest()) ? "是" : "否");
        if ("-1".equals(interfaceInfo.getLifeCycle())) {
            data.put("lifeCycle", interfaceInfo.getPreLifeCycle());
        } else {
            data.put("lifeCycle", interfaceInfo.getLifeCycle());
        }
        data.put("errorStatus", interfaceInfo.getErrorStatus());
        return data;
    }

    private List<InterfaceInfo> queryByType(String fbType, String interfaceName, String isEditTest) {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setFbType(fbType);
        interfaceInfo.setIsEditTest(isEditTest);
        if (StringUtils.isNotEmpty(interfaceName)) {
            interfaceInfo.setInterfaceName(interfaceName);
        }
        List<InterfaceInfo> interfaceInfoList = interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
        return interfaceInfoList;
    }

    @Resource
    private IProcessBranchConditionService processBranchConditionService;

    @Resource
    private IProcessBranchConditionDetailService processBranchConditionDetailService;

    @Resource
    private IProcessBranchEndService processBranchEndService;

    @Resource
    private IErrorCodeService errorCodeService;

    private List<Map<String, Object>> queryProcessBranch(Long interfaceId) {
        ProcessBranch processBranch = new ProcessBranch();
        processBranch.setInterfaceId(interfaceId);
        List<ProcessBranch> processBranchList = this.processBranchService.selectProcessBranchList(processBranch);
        List<Map<String, Object>> result = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(processBranchList)) {
            for (ProcessBranch branch : processBranchList) {
                Map<String, Object> data = new HashMap<>();
                data.put("processBranchId",branch.getProcessBranchId());
                data.put("processBranchCode",branch.getProcessBranchCode());
                data.put("interfaceId",branch.getInterfaceId());
                data.put("interfaceType",branch.getInterfaceType());
                data.put("parentProcessBranchId",branch.getParentProcessBranchId());
                data.put("entityId",branch.getEntityId());
                data.put("type",branch.getType());
                data.put("level",branch.getLevel());
                data.put("sortNum",branch.getSortNum());
                if (branch.getType().equals("1")) {
                    VirtualUsage virtualUsage = new VirtualUsage();
                    virtualUsage.setId(branch.getEntityId());
                    List<VirtualUsage> virtualUsages = virtualUsageService.selectVirtualUsages(virtualUsage);
                    if (CollectionUtil.isNotEmpty(virtualUsages)) {
                        data.put("processBranchName", virtualUsages.get(0).getSlaveInterfaceName());
                        data.put("virtualUsage", convertProcessBranchVirtualUsage(branch.getProcessBranchId(), branch.getEntityId(), virtualUsages.get(0)));
                    }
                } else if (branch.getType().equals("2")) {
                    ProcessBranchCondition processBranchCondition = processBranchConditionService.selectProcessBranchConditionByBranchConditionId(branch.getEntityId());
                    data.put("processBranchName", processBranchCondition.getBranchConditionName());
                    data.put("branchCondition", convertProcessBranchBranchCondition(branch.getProcessBranchId(), branch.getEntityId(), processBranchCondition));
                } else if (branch.getType().equals("4")) {
                    VirtualUsageGroup virtualUsageGroup = virtualUsageGroupService.selectVirtualUsageGroupById(branch.getEntityId());
                    if (virtualUsageGroup == null) continue;
                    data.put("processBranchName", virtualUsageGroup.getGroupName());
                    data.put("virtualUsageGroup", convertVirtualUsageGroup(branch.getProcessBranchId(), virtualUsageGroup));
                } else {
                    ProcessBranchEnd end = this.processBranchEndService.selectProcessBranchEndByBranchEndId(branch.getEntityId());
                    Map<String, Object> endData = new HashMap<>();
                    endData.put("branchEndId", end.getBranchEndId());
                    endData.put("endType", end.getEndType());
                    endData.put("endWay", end.getEndWay());
                    if (end.getEndWay().equals("1")) {
                        data.put("processBranchName", "正常结束");
                    } else if (end.getEndWay().equals("2")) {
                        data.put("processBranchName", "异常结束");
                    } else if (end.getEndWay().equals("3")) {
                        data.put("processBranchName", "跳出循环");
                    } else {
                        data.put("processBranchName", "继续循环");
                    }
                    endData.put("errorCode", end.getErrorCode());
                    if (end.getErrorCode() != null) {
                        ErrorCode errorCode = new ErrorCode();
                        errorCode.setErrorCode(end.getErrorCode());
                        List<ErrorCode> errorCodes = this.errorCodeService.selectErrorCodeList(errorCode);
                        if (CollectionUtil.isNotEmpty(errorCodes)) {
                            endData.put("errorDetail", errorCodes.get(0).getErrorCodeDetail());
                        }
                    }
                    data.put("branchEnd", endData);
                }
                result.add(data);
            }
        }
        return result;
    }

    @Resource
    private IVirtualUsageGroupDetailService virtualUsageGroupDetailService;

    private Map<String, Object> convertVirtualUsageGroup(Long processBranchId, VirtualUsageGroup virtualUsageGroup) {
        Map<String, Object> data = new HashMap<>();
        data.put("virtualUseCaseId", virtualUsageGroup.getId() + "_2");
        data.put("virtualUseCaseBranchId", virtualUsageGroup.getId() + "_"+ processBranchId + "_2");
        data.put("requestDtoName", virtualUsageGroup.getInParamDtoName());
        data.put("isMaster", virtualUsageGroup.getIsMaster());
        data.put("responseDtoName", virtualUsageGroup.getOutParamDtoName());
        data.put("virtualMethodDesc", virtualUsageGroup.getGroupDescription());
        data.put("virtualMethodName", virtualUsageGroup.getGroupName());
        data.put("virtualMethodEnName", virtualUsageGroup.getMethodName());
        Map<String, Object> model = new HashMap<>();
        model.put("virtualUsageModelContent", virtualUsageGroup.getSelfModel());
        model.put("virtualUsageModelCode", virtualUsageGroup.getModel());
        data.put("virtualUsageModel", model);

        List<InterfaceParam> requestList = null;
        String interfaceType = "5";
        requestList = this.interfaceInfoService.virtualUsageInParamList(interfaceType, virtualUsageGroup.getId(), processBranchId, null);
        List<Map<String, Object>> requestBody = new ArrayList<>();
        List<Map<String, Object>> response = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(requestList)) {
            for (InterfaceParam interfaceParam : requestList) {
                requestBody.add(convertField(interfaceParam, virtualUsageGroup.getId(), "1", interfaceType));
            }
        }
        List<InterfaceParam> responseList = this.interfaceInfoService.paramList(interfaceType, virtualUsageGroup.getId(), "2");
        if (CollectionUtil.isNotEmpty(responseList)) {
            for (InterfaceParam interfaceParam : responseList) {
                response.add(convertField(interfaceParam, processBranchId, "2", interfaceType));
            }
        }
        data.put("requestBody", requestBody);
        data.put("response", response);
        List<VirtualUsage> virtualUsages = virtualUsageGroupDetailService.virtualUsageList(virtualUsageGroup.getId());
        data.put("virtualUsages", convertGroupVirtualUsageList(virtualUsages, virtualUsageGroup.getId()));
        return data;
    }

    private List<Map<String, Object>> convertGroupVirtualUsageList(List<VirtualUsage> virtualUsages, Long virtualUsageGroupId) {
        List<Map<String, Object>> virtualUseCase = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(virtualUsages)) {
            for (VirtualUsage usage : virtualUsages) {
                Map<String, Object> data = new HashMap<>();
                data.put("virtualMethodId", usage.getInterfaceId());
                data.put("virtualMethodName", usage.getAliasName());
                data.put("virtualMethodDesc", usage.getDescription());
                data.put("isMaster", usage.getIsMaster());
                data.put("sortNum", usage.getSortNum());
                data.put("appType", usage.getSlaveAppType());
                data.put("methodType", "1".equals(usage.getSlaveFbType()) ? "METHOD" : "2".equals(usage.getSlaveFbType()) ? "BFF" : "DUBBO");

                Map<String, Object> model = new HashMap<>();
                model.put("virtualUsageModelContent", usage.getSelfModel());
                model.put("virtualUsageModelCode", usage.getModel());
                SysDictData virtualUsageModel = getDictRemark("virtualUsageModel", usage.getModel());
                if (virtualUsageModel != null) {
                    model.put("virtualUsageModelRemark", virtualUsageModel.getRemark());
                    model.put("isCreateMethod", virtualUsageModel.getIsCreateMethod());
                }
                model.put("outParamStrategy", usage.getIsAllowEmpty());
                data.put("virtualUsageModel", model);
                convertGroupParam(usage.getId(), "3", data, virtualUsageGroupId);
                virtualUseCase.add(data);
            }
        }
        return virtualUseCase;
    }


    private Map<String, Object> convertGroupParam(Long interfaceId, String interfaceType, Map<String, Object> data, Long virtualUsageGroupId) {
        List<Map<String, Object>> requestBody = new ArrayList<>();
        List<Map<String, Object>> response = new ArrayList<>();
        List<InterfaceParam> requestList = null;
        if ("3".equals(interfaceType)) {
            requestList = this.interfaceInfoService.virtualUsageInParamList(interfaceType, interfaceId, null, virtualUsageGroupId);
        } else {
            requestList = this.interfaceInfoService.paramList(interfaceType, interfaceId, "1");
        }
        if (CollectionUtil.isNotEmpty(requestList)) {
            for (InterfaceParam interfaceParam : requestList) {
                requestBody.add(convertGroupField(interfaceParam, "1", interfaceType,virtualUsageGroupId));
            }
        }
        List<InterfaceParam> responseList = this.interfaceInfoService.paramList(interfaceType, interfaceId, "2");
        if (CollectionUtil.isNotEmpty(responseList)) {
            Map<Long, List<VirtualUsageFieldMerge>> mergeRecord = new HashMap<>();
            // 字段融合
            VirtualUsageFieldMerge virtualUsageFieldMerge = new VirtualUsageFieldMerge();
            virtualUsageFieldMerge.setVirtualUsageId(interfaceId);
            List<VirtualUsageFieldMerge> virtualUsageFieldMerges = this.virtualUsageFieldMergeService.selectVirtualUsageFieldMergeList(virtualUsageFieldMerge);
            if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges)) {
                mergeRecord = virtualUsageFieldMerges.stream().collect(Collectors.groupingBy(VirtualUsageFieldMerge::getObjectId));
            }
            for (InterfaceParam interfaceParam : responseList) {
                if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                    for (InterfaceParam child : interfaceParam.getChildren()) {
                        List<VirtualUsageFieldMerge> virtualUsageFieldMerges2 = mergeRecord.get(child.getId());
                        if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges2)) {
                            child.setMergeId(virtualUsageFieldMerges2.get(0).getMergeObjectId());
                        }
                    }
                }
                response.add(convertGroupField(interfaceParam, "2", interfaceType,virtualUsageGroupId));
            }
        }
        data.put("requestBody", requestBody);
        data.put("response", response);
        return data;
    }


    private Map<String, Object> convertGroupField(InterfaceParam interfaceParam, String isInParam, String interfaceType, Long virtualUsageGroupId) {
        Map<String, Object> data = new HashMap<>();
        data.put("paramId", interfaceParam.getFieldId());
        data.put("condition", interfaceParam.getOperate());
        data.put("conditionWay", interfaceParam.getConditionWay());
        data.put("uniqueId", interfaceParam.getId() + "_1_" + virtualUsageGroupId);
        if ("1".equals(isInParam) && interfaceParam.getDataRelationId() != null && interfaceParam.getDataRelationType() != null) {
            if (interfaceParam.getVirtualUsageGroupId() != null) {
                data.put("uniqueSourceId", interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType() + "_" + interfaceParam.getVirtualUsageGroupId());
            } else {
                data.put("uniqueSourceId", interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType() + "_" + virtualUsageGroupId);
            }
        }
        data.put("fieldName", interfaceParam.getFieldName());
        data.put("fieldEnName", interfaceParam.getFieldEnName());
        data.put("tableName", interfaceParam.getTableName());
        data.put("tableEnName", interfaceParam.getTableEnName());
        Map<String, Object> paramDetail = this.paramDetail(interfaceParam, interfaceType, "1", isInParam);
        if (interfaceParam.getObjectType().equals("2")) {
            data.put("isCollection", "是");
            data.put("paramId", interfaceParam.getFieldId());
            data.put("dtoName", StringUtils.isNotEmpty(interfaceParam.getObjectDtoName()) ? interfaceParam.getObjectDtoName().toString() : interfaceParam.getObjectDtoName());
            if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                List<Map<String, Object>> children = new ArrayList<>();
                for (InterfaceParam child : interfaceParam.getChildren()) {
                    Map<String, Object> childData = new HashMap<>();
                    childData.put("paramId", child.getFieldId());
                    childData.put("condition", child.getOperate());
                    childData.put("conditionWay", child.getConditionWay());
                    childData.put("uniqueId", child.getId() + "_2_" + virtualUsageGroupId);
                    if ("1".equals(isInParam) && child.getDataRelationId() != null && child.getDataRelationType() != null) {
                        if (child.getVirtualUsageGroupId() != null) {
                            childData.put("uniqueSourceId", child.getDataRelationId() + "_" + child.getDataRelationType() + "_" + child.getVirtualUsageGroupId());
                        } else {
                            childData.put("uniqueSourceId", child.getDataRelationId() + "_" + child.getDataRelationType() + "_" + virtualUsageGroupId);
                        }
                    }
                    if ("2".equals(isInParam)) {
                        if ("3".equals(interfaceType)) {
                            childData.put("mergeId", "merge_" + child.getId());
                            if (child.getMergeId() != null) {
                                childData.put("mergeSourceId", "merge_" + child.getMergeId());
                            }
                        }
                    }
                    childData.put("fieldName", child.getFieldName());
                    childData.put("fieldEnName", child.getFieldEnName());
                    childData.put("tableName", child.getTableName());
                    childData.put("tableEnName", child.getTableEnName());
                    Map<String, Object> childParamDetail = this.paramDetail(child, interfaceType, "2", isInParam);
                    childData.put("paramDetail", childParamDetail);
                    children.add(childData);
                }
                data.put("collectionFieldList", children);
            }
        } else {
            data.put("isCollection", "否");
        }
        data.put("paramDetail", paramDetail);
        return data;
    }

    private Map<String, Object> convertProcessBranchBranchCondition(Long processBranchId, Long entityId, ProcessBranchCondition processBranchCondition) {
        Map<String, Object> data = new HashMap<>();
        if (processBranchCondition != null) {
            data.put("branchConditionId", processBranchCondition.getBranchConditionId());
            data.put("branchConditionName", processBranchCondition.getBranchConditionName());
            data.put("type", processBranchCondition.getType());
            data.put("joinCondition", processBranchCondition.getJoinCondition());
            data.put("branchConditionDesc", processBranchCondition.getBranchConditionDesc());
            ProcessBranchConditionDetail processBranchConditionDetail = new ProcessBranchConditionDetail();
            processBranchConditionDetail.setBranchConditionId(entityId);
            List<ProcessBranchConditionDetail> details = this.processBranchConditionDetailService.selectProcessBranchConditionDetails(processBranchConditionDetail);
            if (CollectionUtil.isNotEmpty(details)) {
                Map<String, List<ProcessBranchConditionDetail>> record = new TreeMap<>();
                for (ProcessBranchConditionDetail detail : details) {
                    List<ProcessBranchConditionDetail> processBranchConditionDetails = record.computeIfAbsent(detail.getBranchConditionGroupId(), key -> new ArrayList<>());
                    processBranchConditionDetails.add(detail);
                }
                List<Map<String, Object>> branchConditionGroup = new ArrayList<>();
                for (Map.Entry<String, List<ProcessBranchConditionDetail>> stringListEntry : record.entrySet()) {
                    Map<String, Object> group = new HashMap<>();
                    List<ProcessBranchConditionDetail> details2 = stringListEntry.getValue();
                    group.put("joinCondition", details2.get(0).getJoinCondition());
                    List<Map<String, Object>> detailGroup = new ArrayList<>();
                    for (int i = 0; i < details2.size(); i++) {
                        Map<String, Object> d = new HashMap<>();
                        ProcessBranchConditionDetail detail = details2.get(i);
                        d.put("branchConditionGroupId", detail.getBranchConditionGroupId());
                        d.put("objectCategory", detail.getObjectCategory());
                        String objectType = detail.getObjectType();
                        String type = "3".equals(objectType) ? "2" : "1";
                        if (detail.getObjectProcessBranchId() != null && detail.getObjectProcessBranchId() != 0) {
                            d.put("objectId", detail.getObjectId() + "_" + type + "_" + detail.getObjectProcessBranchId());
                        } else {
                            d.put("objectId", detail.getObjectId() + "_" + type);
                        }
                        d.put("branchConditionDetailDictCode", detail.getBranchConditionDetailDictCode());
                        d.put("interfaceId", detail.getInterfaceId());
                        d.put("objectProcessBranchId", detail.getObjectProcessBranchId());
                        d.put("virtualUseCaseBranchId", detail.getInterfaceId() + "_" + detail.getObjectProcessBranchId());
                        d.put("objectType", objectType);
                        d.put("judgeConditionDictCode", detail.getJudgeConditionDictCode());
                        if (!"IS_NULL".equals(detail.getJudgeConditionDictCode()) && !"IS_NOT_NULL".equals(detail.getJudgeConditionDictCode())) {
                            d.put("contractValue", detail.getContractValue());
                        }
                        d.put("paramId", detail.getFieldId());
                        d.put("fieldName", detail.getFieldName());
                        d.put("fieldEnName", detail.getFieldEnName());
                        d.put("tableName", detail.getTableName());
                        d.put("tableEnName", detail.getTableEnName());
                        d.put("isFieldEnum", "Y".equals(detail.getIsFieldEnum()) ? "是" : "否");
                        detailGroup.add(d);
                    }
                    group.put("branchConditionDetail", detailGroup);
                    branchConditionGroup.add(group);
                }
                data.put("branchConditionGroup", branchConditionGroup);
            }
        }
        return data;
    }

    private Map<String, Object> convertProcessBranchVirtualUsage(Long processBranchId, Long entityId, VirtualUsage virtualUsage) {
        Map<String, Object> data = new HashMap<>();
        data.put("virtualMethodId", virtualUsage.getInterfaceId());
        data.put("virtualMethodName", virtualUsage.getSlaveInterfaceName());
        data.put("virtualMethodEnName", virtualUsage.getDubboUrl());
        data.put("virtualMethodDesc", virtualUsage.getDescription());
        data.put("isMaster", virtualUsage.getIsMaster());
        data.put("virtualUseCaseBranchId", entityId + "_" + processBranchId);
        data.put("appType", virtualUsage.getSlaveAppType());
        data.put("methodType", "1".equals(virtualUsage.getSlaveFbType()) ? "METHOD" : "2".equals(virtualUsage.getSlaveFbType()) ? "BFF" : "DUBBO");

        if (StringUtils.isNotEmpty(virtualUsage.getErrorCode())) {
            data.put("errorCode", virtualUsage.getErrorCode());
            ErrorCode errorCode = new ErrorCode();
            errorCode.setErrorCode(virtualUsage.getErrorCode());
            List<ErrorCode> errorCodes = this.errorCodeService.selectErrorCodeList(errorCode);
            if (CollectionUtil.isNotEmpty(errorCodes)) {
                data.put("errorDetail", errorCodes.get(0).getErrorCodeDetail());
            }
        }
        Map<String, Object> model = new HashMap<>();
        model.put("virtualUsageModelContent", virtualUsage.getSelfModel());
        model.put("virtualUsageModelCode", virtualUsage.getModel());
        model.put("outParamStrategy", virtualUsage.getIsAllowEmpty());
        data.put("virtualUsageModel", model);
        SysDictData virtualUsageModel = getDictRemark("virtualUsageModel", virtualUsage.getModel());
        if (virtualUsageModel != null) {
            model.put("virtualUsageModelRemark", virtualUsageModel.getRemark());
            model.put("isCreateMethod", virtualUsageModel.getIsCreateMethod());
        }
        convertProcessBranchVirtualUsageParam(entityId, processBranchId, data);
        return data;
    }

    private Map<String, Object> convertProcessBranchVirtualUsageParam(Long interfaceId, Long processBranchId, Map<String, Object> data) {
        List<Map<String, Object>> requestBody = new ArrayList<>();
        List<Map<String, Object>> response = new ArrayList<>();
        List<InterfaceParam> requestList = null;
        String interfaceType = "3";
        requestList = this.interfaceInfoService.virtualUsageInParamList(interfaceType, interfaceId, processBranchId, null);

        if (CollectionUtil.isNotEmpty(requestList)) {
            for (InterfaceParam interfaceParam : requestList) {
                requestBody.add(convertField(interfaceParam, processBranchId, "1", interfaceType));
            }
        }
        List<InterfaceParam> responseList = this.interfaceInfoService.paramList(interfaceType, interfaceId, "2");
        if (CollectionUtil.isNotEmpty(responseList)) {
            Map<Long, List<VirtualUsageFieldMerge>> mergeRecord = new HashMap<>();
            // 字段融合
            VirtualUsageFieldMerge virtualUsageFieldMerge = new VirtualUsageFieldMerge();
            virtualUsageFieldMerge.setVirtualUsageId(interfaceId);
            List<VirtualUsageFieldMerge> virtualUsageFieldMerges = this.virtualUsageFieldMergeService.selectVirtualUsageFieldMergeList(virtualUsageFieldMerge);
            if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges)) {
                mergeRecord = virtualUsageFieldMerges.stream().collect(Collectors.groupingBy(VirtualUsageFieldMerge::getObjectId));
            }
            for (InterfaceParam interfaceParam : responseList) {
                if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                    for (InterfaceParam child : interfaceParam.getChildren()) {
                        List<VirtualUsageFieldMerge> virtualUsageFieldMerges2 = mergeRecord.get(child.getId());
                        if (CollectionUtil.isNotEmpty(virtualUsageFieldMerges2)) {
                            child.setMergeId(virtualUsageFieldMerges2.get(0).getMergeObjectId());
                        }
                    }
                }
                response.add(convertField(interfaceParam, processBranchId, "2", interfaceType));
            }
        }
        data.put("requestBody", requestBody);
        data.put("response", response);
        return data;
    }

    private Map<String, Object> convertField(InterfaceParam interfaceParam, Long processBranchId, String isInParam, String interfaceType) {
        Map<String, Object> data = new HashMap<>();

        data.put("paramId", interfaceParam.getFieldId());
        data.put("uniqueId", interfaceParam.getId() + "_1" + "_" + processBranchId);
        if ("2".equals(isInParam)) {
            data.put("uniqueOutId", "out_" + interfaceParam.getId() + "_1");
            data.put("isTree", interfaceParam.getIsTree());
            data.put("nodeType", interfaceParam.getNodeType());
        }
        if (interfaceParam.getDataRelationId() != null && interfaceParam.getDataRelationType() != null) {
            if (interfaceParam.getSourceProcessBranchId() != null && interfaceParam.getSourceProcessBranchId() != 0) {
                data.put("uniqueSourceId", interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType()+"_" +interfaceParam.getSourceProcessBranchId());
            } else {
                data.put("uniqueSourceId", interfaceParam.getDataRelationId() + "_" + interfaceParam.getDataRelationType());
            }
        }
        data.put("fieldName", interfaceParam.getFieldName());
        data.put("fieldEnName", interfaceParam.getFieldEnName());
        data.put("tableName", interfaceParam.getTableName());
        data.put("tableEnName", interfaceParam.getTableEnName());
        Map<String, Object> paramDetail = this.paramDetail(interfaceParam, "3", "1", isInParam);
        if (interfaceParam.getObjectType().equals("2")) {
            data.put("isCollection", "是");
            data.put("paramId", interfaceParam.getFieldId());
            data.put("dtoName", StringUtils.isNotEmpty(interfaceParam.getObjectDtoName()) ? interfaceParam.getObjectDtoName().toString() : interfaceParam.getObjectDtoName());
            if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                List<Map<String, Object>> children = new ArrayList<>();
                for (InterfaceParam child : interfaceParam.getChildren()) {
                    Map<String, Object> childData = new HashMap<>();
                    childData.put("paramId", child.getFieldId());
                    childData.put("uniqueId", child.getId() + "_2" + "_" + processBranchId);
                    if ("2".equals(isInParam)) {
                        childData.put("uniqueOutId", "out_" + child.getId() + "_2");
                        if ("3".equals(interfaceType)) {
                            childData.put("mergeId", "merge_" + child.getId());
                            if (child.getMergeId() != null) {
                                childData.put("mergeSourceId", "merge_" + child.getMergeId());
                            }
                        }
                    }
                    if (child.getSourceProcessBranchId() != null && child.getSourceProcessBranchId() != 0) {
                        childData.put("uniqueSourceId", child.getDataRelationId() + "_" + child.getDataRelationType()+"_" +child.getSourceProcessBranchId());
                    } else {
                        childData.put("uniqueSourceId", child.getDataRelationId() + "_" + child.getDataRelationType());
                    }
                    childData.put("fieldName", child.getFieldName());
                    childData.put("fieldEnName", child.getFieldEnName());
                    childData.put("tableName", child.getTableName());
                    childData.put("tableEnName", child.getTableEnName());
                    Map<String, Object> childParamDetail = this.paramDetail(child, "3", "2", isInParam);
                    childData.put("paramDetail", childParamDetail);
                    children.add(childData);
                }
                data.put("collectionFieldList", children);
            }
        } else {
            data.put("isCollection", "否");
        }
        data.put("paramDetail", paramDetail);
        return data;
    }
}